home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / src / exampleCode / opengl / utilities / xglinfo / xglinfo.c < prev    next >
C/C++ Source or Header  |  1996-11-11  |  28KB  |  967 lines

  1. /*
  2.  * 
  3.  *           Copyright (c) Digital Equipment Corporation, 1993
  4.  * 
  5.  *                          All Rights Reserved
  6.  * 
  7.  * Permission to use, copy, modify, and distribute  this software and its
  8.  * documentation for any  purpose   and without fee  is  hereby  granted,
  9.  * provided that the above copyright notice appear in all copies and that
  10.  * both  that  copyright  notice  and  this  permission notice appear  in
  11.  * supporting documentation, and that the name of Digital  not be used in
  12.  * advertising or publicity  pertaining to distribution  of the  software
  13.  * without specific, written prior permission.
  14.  * 
  15.  * DIGITAL DISCLAIMS   ALL  WARRANTIES WITH   REGARD   TO  THIS SOFTWARE,
  16.  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  17.  * EVENT   SHALL  DIGITAL  BE   LIABLE  FOR  ANY SPECIAL,   INDIRECT   OR
  18.  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
  19.  * USE, DATA OR PROFITS, WHETHER IN AN ACTION  OF CONTRACT, NEGLIGENCE OR
  20.  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  21.  * PERFORMANCE OF THIS SOFTWARE.
  22.  * 
  23.  */
  24. /*
  25.  * HISTORY
  26.  * $Log: xglinfo.c,v $
  27.  * Revision 1.1  1995/01/27  18:06:45  dave
  28.  * Initial revision
  29.  *
  30.  * Revision 1.1.2.3  1993/06/18  15:02:52  John_Dennis
  31.  *     change copyright token to free copyright token
  32.  *     [1993/06/18  14:59:33  John_Dennis]
  33.  *
  34.  * Revision 1.1.2.2  1993/06/16  20:33:39  John_Dennis
  35.  *     various lint clean ups, nicer formatting, etc.
  36.  *     [1993/06/16  20:13:42  John_Dennis]
  37.  * 
  38.  *     Initial Version by John Dennis
  39.  *     [1993/06/15  20:07:25  John_Dennis]
  40.  * 
  41.  * $EndLog$
  42.  */
  43. /*****************************************************************************/
  44. /******************************** Documentation ******************************/
  45. /*****************************************************************************/
  46.  
  47. /*
  48.  * See man page for full documentation.
  49.  *
  50.  * Written by John Dennis, Digital Equipment Corporation.
  51.  * jdennis@mlo.dec.com
  52.  *
  53.  * With thanks and credit to Jim Fulton who wrote the original version of
  54.  * xdpyinfo while at MIT which served as a starting point for this code.
  55.  */
  56.  
  57. /*****************************************************************************/
  58. /******************************* Include Files *******************************/
  59. /*****************************************************************************/
  60.  
  61. #include <stdio.h>
  62. #include <string.h>
  63. #include <stdlib.h>
  64. #include <X11/Xlib.h>
  65. #include <X11/Xutil.h>
  66. #include <GL/gl.h>
  67. #include <GL/glx.h>
  68. #include "global.h"
  69.  
  70. /*****************************************************************************/
  71. /****************************** Internal Defines *****************************/
  72. /*****************************************************************************/
  73.  
  74. #define GL_GET_CONFIG(_config, _pValue)                                      \
  75. {                                                                            \
  76.   switch (result = glXGetConfig(dpy, visual, _config, (_pValue))) {          \
  77.   case Success:                                                              \
  78.     break;                                                                   \
  79.   case GLX_NO_EXTENSION:                                                     \
  80.     printf("ERROR glXGetConfig %s return GLX_NO_EXTENSION, visuaID 0x%lx\n", \
  81.           "_config", visual->visualid);                                      \
  82.     break;                                                                   \
  83.   case GLX_BAD_SCREEN:                                                       \
  84.     printf("ERROR glXGetConfig %s return GLX_BAD_SCREEN, visuaID 0x%lx\n",   \
  85.           "_config", visual->visualid);                                      \
  86.     break;                                                                   \
  87.   case GLX_BAD_ATTRIBUTE:                                                    \
  88.     printf("ERROR glXGetConfig %s return GLX_BAD_ATTRIBUTE, visuaID 0x%lx\n",\
  89.           "_config", visual->visualid);                                      \
  90.     break;                                                                   \
  91.   case GLX_BAD_VISUAL:                                                       \
  92.     printf("ERROR glXGetConfig %s return GLX_BAD_VISUAL, visuaID 0x%lx\n",   \
  93.           "_config", visual->visualid);                                      \
  94.     break;                                                                   \
  95.   default:                                                                   \
  96.     printf("ERROR glXGetConfig %s return unknown error %d, visuaID 0x%lx\n", \
  97.           "_config", result, visual->visualid);                              \
  98.     break;                                                                   \
  99.   }                                                                          \
  100. }
  101.  
  102. /*****************************************************************************/
  103. /************************** Internal Type Definitions ************************/
  104. /*****************************************************************************/
  105.  
  106. typedef struct GLXVisualInfo {
  107.   int useGL;                   /* support GLX rendering */
  108.   int bufferSize;               /* depth of the color buffer */
  109.   int level;                   /* level in plane stacking */
  110.   int rgba;                   /* true if RGBA mode */
  111.   int doubleBuffer;               /* double buffering supported */
  112.   int stereo;                   /* stereo buffering supported */
  113.   int auxBuffers;               /* number of aux buffers */
  114.   int redSize;                   /* number of red component bits */
  115.   int greenSize;               /* number of green component bits */
  116.   int blueSize;                   /* number of blue component bits */
  117.   int alphaSize;               /* number of alpha component bits */
  118.   int depthSize;               /* number of depth bits */
  119.   int stencilSize;               /* number of stencil bits */
  120.   int accumRedSize;               /* number of red accum bits */
  121.   int accumGreenSize;               /* number of green accum bits */
  122.   int accumBlueSize;               /* number of blue accum bits */
  123.   int accumAlphaSize;               /* number of alpha accum bits */
  124. } GLXVisualInfo;
  125.  
  126. /*****************************************************************************/
  127. /**********************  External Function Declarations  *********************/
  128. /*****************************************************************************/
  129.  
  130. /*****************************************************************************/
  131. /**********************  Internal Function Declarations  *********************/
  132. /*****************************************************************************/
  133.  
  134. static void
  135. Usage(
  136.   void
  137. );
  138.  
  139. static void
  140. ProcessArgs(
  141.          int argc   ,
  142.          char       *argv[]
  143. );
  144.  
  145. void
  146. PrintEventMask (
  147.     int indent,                /* amount by which to indent */
  148.     unsigned long mask                /* event mask */
  149. );
  150.  
  151. void
  152. PrintExtensionInfo(
  153.   Display    *dpy,
  154.   int         fieldNameLen,
  155.   int          indent
  156. );
  157.  
  158. void
  159. PrintPixmapFormats(
  160.   Display    *dpy,
  161.   int         fieldNameLen,
  162.   int          indent
  163. );
  164.  
  165. void
  166. PrintWindowFocus(
  167.   Display    *dpy,
  168.   int         fieldNameLen
  169. );
  170.  
  171. void
  172. PrintDisplayInfo(
  173.   Display    *dpy,
  174.   int         fieldNameLen
  175. );
  176.  
  177. int
  178. GetGLVisualInfo (
  179.     Display    *dpy,
  180.     XVisualInfo *visual,
  181.     GLXVisualInfo *glVisual
  182. );
  183.  
  184. int
  185. PrintCookedVisualInfo (
  186.     Display    *dpy,
  187.     XVisualInfo *visual,
  188.     int indent
  189. );
  190.  
  191. int
  192. PrintRawVisualInfo (
  193.     Display    *dpy,
  194.     XVisualInfo *visual,
  195.     int indent
  196. );
  197.  
  198. void
  199. PrintScreenInfo(
  200.   Display    *dpy,
  201.   int         scr,
  202.   int         fieldNameLen,
  203.   int          indent
  204. );
  205.  
  206. void
  207. PrintScreenVisualInfo(
  208.   Display    *dpy,
  209.   int         scr,
  210.   int         fieldNameLen,
  211.   int          indent
  212. );
  213.  
  214. /*****************************************************************************/
  215. /*************************  External Global Variables  ***********************/
  216. /*****************************************************************************/
  217.  
  218. char       *ProgramName;
  219.  
  220. /*****************************************************************************/
  221. /*************************  Internal Global Variables  ***********************/
  222. /*****************************************************************************/
  223.  
  224. static char       *displayname = NULL;    /* server to contact */
  225. static int         printDisplayInfo = GL_TRUE;
  226. static int         printScreenInfo = GL_TRUE;
  227. static int         printVisualInfo = GL_TRUE;
  228. static int         printCookedVisualInfo = GL_TRUE;
  229. static int         printRawVisualInfo = GL_FALSE;
  230.  
  231. static int        pageWidth = 80;
  232. static GLint       glErrorBase, glEventBase;
  233. static GLint       glMajorVersion, glMinorVersion;
  234. static Bool        dpyHasGL = GL_FALSE;
  235.  
  236. /*****************************************************************************/
  237. /***************************  Internal Functions  ****************************/
  238. /*****************************************************************************/
  239.  
  240. static void
  241. Usage(
  242.   void
  243. )
  244. {
  245.   fprintf(stderr, "usage:  %s [-display displayname]\n\n",
  246.       ProgramName);
  247.   fprintf(stderr, "  the following options take a '+' or '-' switch\n");
  248.   fprintf(stderr, "  a '+' turns the option on, a '-' turns the option off\n\n");
  249.   fprintf(stderr, "  [+-printDisplayInfo] [+-printScreenInfo] [+-printVisualInfo]\n");
  250.   fprintf(stderr, "  [+-printCookedVisualInfo] [+-printRawVisualInfo]\n");
  251.   exit(1);
  252. }
  253.  
  254. static void
  255. ProcessArgs(
  256.          int argc   ,
  257.          char       *argv[]
  258. )
  259. {
  260.   int         i;
  261.     char       *arg;
  262.   char        switchChar;
  263.  
  264.   ProgramName = argv[0];
  265.  
  266.   for (i = 1; i < argc; i++) {
  267.     arg = argv[i];
  268.     switchChar = arg[0];
  269.  
  270.     if (switchChar == '-' || switchChar == '+') {
  271.       arg++;
  272.       if (strcmp(arg, "display") == 0) {
  273.     if (switchChar == '-') {
  274.       if (++i >= argc) goto missing;
  275.       displayname = argv[i];
  276.     }
  277.     else goto unknown;
  278.       }
  279.       else if (strcmp(arg, "printDisplayInfo") == 0) {
  280.     if (switchChar == '+')
  281.       printDisplayInfo = GL_TRUE;
  282.     else
  283.       printDisplayInfo = GL_FALSE;
  284.       }
  285.       else if (strcmp(arg, "printScreenInfo") == 0) {
  286.     if (switchChar == '+')
  287.       printScreenInfo = GL_TRUE;
  288.     else
  289.       printScreenInfo = GL_FALSE;
  290.       }
  291.       else if (strcmp(arg, "printVisualInfo") == 0) {
  292.     if (switchChar == '+')
  293.       printVisualInfo = GL_TRUE;
  294.     else
  295.       printVisualInfo = GL_FALSE;
  296.       }
  297.       else if (strcmp(arg, "printRawVisualInfo") == 0) {
  298.     if (switchChar == '+')
  299.       printRawVisualInfo = GL_TRUE;
  300.     else
  301.       printRawVisualInfo = GL_FALSE;
  302.       }
  303.       else if (strcmp(arg, "printCookedVisualInfo") == 0) {
  304.     if (switchChar == '+')
  305.       printCookedVisualInfo = GL_TRUE;
  306.     else
  307.       printCookedVisualInfo = GL_FALSE;
  308.       }
  309.       else goto unknown;
  310.     }
  311.     else {
  312.       goto unknown;
  313.     }
  314.   }
  315.   return;
  316.  
  317.   unknown:
  318.       fprintf(stderr, "unknown arg: %s\n", argv[i]);
  319.       Usage();
  320.     
  321.   missing:
  322.       fprintf(stderr, "missing arg for: %s\n", argv[i]);
  323.       Usage();
  324. }
  325.  
  326. void
  327. PrintEventMask (
  328.     int indent,                /* amount by which to indent */
  329.     unsigned long mask                /* event mask */
  330. )
  331. {
  332.   char buf[1024];
  333.     int i, pad;
  334.     int nameWidth = 21;
  335.     unsigned long bit;
  336.     int len = indent;
  337.     int nameLen;
  338.     int bitsfound = 0;
  339.     char *name;
  340.  
  341.     for (i = 0; i < indent; i++) buf[i] = ' ';
  342.  
  343.     for (bit = 1; mask; bit <<= 1) {
  344.       if (bit & mask) {
  345.     mask ^= bit;               /* clear bit from mask */
  346.     name = EventMaskName((long)bit);
  347.     nameLen = strlen(name);
  348.     if (nameLen >= nameWidth) nameLen = nameWidth - 1; /* -1 for pad */
  349.     pad = nameWidth - nameLen;
  350.     if (len + nameLen > pageWidth) {
  351.       puts (buf);
  352.       len = indent;
  353.     }
  354.     strncpy(buf+len, name, nameLen);
  355.     len += nameLen;
  356.     if (len + pad > pageWidth) {
  357.       buf[len] = 0;
  358.       puts (buf);
  359.       len = indent;
  360.     }
  361.     else {
  362.       for (i = 0; i < pad; i++) buf[len++] = ' ';
  363.     }
  364.     buf[len] = 0;
  365.     bitsfound++;
  366.       }
  367.     }
  368.  
  369.     if (bitsfound) puts (buf);
  370. }
  371.  
  372. void
  373. PrintExtensionInfo(
  374.   Display    *dpy,
  375.   int         fieldNameLen,
  376.   int          indent
  377. )
  378. {
  379.   int         n = 0;
  380.   int         len, lineLen;
  381.   char      **extlist = XListExtensions(dpy, &n);
  382.  
  383.  
  384.   printf("%*s%d total\n",
  385.      fieldNameLen, "Server Extensions:",
  386.      n);
  387.   if (extlist) {
  388.     register int i;
  389.  
  390.     printf("%*s", indent, "");
  391.     lineLen = indent;
  392.     for (i = 0; i < n; i++) {
  393.       len = strlen(extlist[i]);
  394.       len += 2;                   /* for ", " */
  395.       if ((lineLen + len) >= pageWidth) {
  396.     printf("\n%*s", indent, "");
  397.     lineLen = indent;
  398.       }
  399.       printf("%s, ", extlist[i]);
  400.       lineLen += len;
  401.     }
  402.     if (lineLen > indent) printf("\n");
  403.     XFreeExtensionList(extlist);
  404.   }
  405. }
  406.  
  407. void
  408. PrintPixmapFormats(
  409.   Display    *dpy,
  410.   int         fieldNameLen,
  411.   int          indent
  412. )
  413. {
  414.   int i, n;
  415.   XPixmapFormatValues *pmf;
  416.  
  417.   pmf = XListPixmapFormats(dpy, &n);
  418.   printf("%*s%d total\n",
  419.      fieldNameLen, "pixmap formats:",
  420.      n);
  421.   if (pmf) {
  422.     for (i = 0; i < n; i++) {
  423.       printf("%*sdepth %2d, bits_per_pixel %2d, scanline_pad %2d\n",
  424.          indent, "",
  425.          pmf[i].depth, pmf[i].bits_per_pixel, pmf[i].scanline_pad);
  426.     }
  427.     XFree((char *) pmf);
  428.   }
  429. }
  430.  
  431. void
  432. PrintWindowFocus(
  433.   Display    *dpy,
  434.   int         fieldNameLen
  435. )
  436. {
  437.   Window      focusWin;
  438.   int         focusRevert;
  439.  
  440.   XGetInputFocus(dpy, &focusWin, &focusRevert);
  441.   switch (focusWin) {
  442.   case PointerRoot:
  443.   case None:
  444.     printf("%*s%s\n",
  445.        fieldNameLen, "focus:",
  446.        WindowFocusName(focusWin));
  447.     break;
  448.   default:
  449.     printf("%*s0x%lx, revert to %s\n",
  450.        fieldNameLen, "focus window:",
  451.        focusWin, WindowFocusRevertName(focusRevert));
  452.     break;
  453.   }
  454. }
  455.  
  456. void
  457. PrintDisplayInfo(
  458.   Display    *dpy,
  459.   int         fieldNameLen
  460. )
  461. {
  462.   char       *cp;
  463.   int         minkeycode, maxkeycode;
  464.   char        title[256];
  465.   int         i;
  466.   int         titleLen, fillLen;
  467.  
  468.   sprintf(title, " Display %s ", DisplayString(dpy));
  469.   titleLen = strlen(title);
  470.   fillLen = (pageWidth - titleLen) / 2;
  471.   for (i = 0; i < fillLen; i++) printf("%c", '=');
  472.   printf("%s", title);
  473.   for (i = 0; i < fillLen; i++) printf("%c", '=');
  474.   printf("\n");  
  475.  
  476.   printf("%*s%s\n",
  477.      fieldNameLen, "name of display:",
  478.      DisplayString(dpy));
  479.   printf("%*s%d.%d\n",
  480.      fieldNameLen, "version number:",
  481.      ProtocolVersion(dpy), ProtocolRevision(dpy));
  482.   printf("%*s%s\n",
  483.      fieldNameLen, "vendor string:",
  484.      ServerVendor(dpy));
  485.   printf("%*s%d\n",
  486.      fieldNameLen, "vendor release:",
  487.      VendorRelease(dpy));
  488.   printf("%*s%ld bytes\n",
  489.      fieldNameLen, "max request size:",
  490.      XMaxRequestSize(dpy) * 4);
  491.   printf("%*s%d\n",
  492.      fieldNameLen, "motion buffer size:",
  493.      XDisplayMotionBufferSize(dpy));
  494.  
  495.   cp = ByteOrderName(BitmapBitOrder(dpy));
  496.   printf("%*sunit = %d, bit order = %s, padding = %d\n",
  497.      fieldNameLen, "bitmap:",
  498.      BitmapUnit(dpy), cp, BitmapPad(dpy));
  499.  
  500.   cp = ByteOrderName(ImageByteOrder(dpy));
  501.   printf("%*s%s\n",
  502.      fieldNameLen, "image byte order:",
  503.      cp);
  504.  
  505.   XDisplayKeycodes(dpy, &minkeycode, &maxkeycode);
  506.   printf("%*sminimum %d, maximum %d\n",
  507.      fieldNameLen, "keycode range:",
  508.      minkeycode, maxkeycode);
  509.  
  510.   PrintWindowFocus(dpy, fieldNameLen);
  511.  
  512.   printf("%*s%d\n",
  513.      fieldNameLen, "default screen num:",
  514.      DefaultScreen(dpy));
  515.   printf("%*s%d\n",
  516.      fieldNameLen, "number of screens:",
  517.      ScreenCount(dpy));
  518.  
  519.  
  520.   PrintPixmapFormats(dpy, fieldNameLen,
  521.              fieldNameLen > 0 ? fieldNameLen : -fieldNameLen);
  522.   PrintExtensionInfo(dpy, fieldNameLen,
  523.              fieldNameLen > 0 ? fieldNameLen : -fieldNameLen);
  524.  
  525.   printf("%*s",
  526.      fieldNameLen, "GLX Extension:");
  527.   if (dpyHasGL) {
  528.     printf("error base = %d, event base = %d, ",
  529.        glErrorBase, glEventBase);
  530.     if (glXQueryVersion(dpy, &glMajorVersion, &glMinorVersion)) {
  531.       printf("Version %d.%d\n",
  532.          glMajorVersion, glMinorVersion);
  533.     }
  534.     else {
  535.       printf("glXQueryVersion returned error\n");
  536.       exit(1);
  537.     }
  538.   }
  539.   else {
  540.     printf("NONE\n");
  541.   }
  542. }
  543.  
  544. int
  545. GetGLVisualInfo (
  546.     Display    *dpy,
  547.     XVisualInfo *visual,
  548.     GLXVisualInfo *glVisual
  549. )
  550. {
  551.   int result;
  552.  
  553.   if (!dpyHasGL) {
  554.     glVisual->useGL = GL_FALSE;
  555.     return(0);
  556.   }
  557.  
  558.   GL_GET_CONFIG(GLX_USE_GL, &glVisual->useGL);
  559.  
  560.   if (!glVisual->useGL) return(0);
  561.  
  562.   GL_GET_CONFIG(GLX_BUFFER_SIZE, &glVisual->bufferSize);
  563.   GL_GET_CONFIG(GLX_LEVEL, &glVisual->level);
  564.   GL_GET_CONFIG(GLX_RGBA, &glVisual->rgba);
  565.   GL_GET_CONFIG(GLX_DOUBLEBUFFER, &glVisual->doubleBuffer);
  566.   GL_GET_CONFIG(GLX_STEREO, &glVisual->stereo);
  567.   GL_GET_CONFIG(GLX_AUX_BUFFERS, &glVisual->auxBuffers);
  568.   GL_GET_CONFIG(GLX_RED_SIZE, &glVisual->redSize);
  569.   GL_GET_CONFIG(GLX_GREEN_SIZE, &glVisual->greenSize);
  570.   GL_GET_CONFIG(GLX_BLUE_SIZE, &glVisual->blueSize);
  571.   GL_GET_CONFIG(GLX_ALPHA_SIZE, &glVisual->alphaSize);
  572.   GL_GET_CONFIG(GLX_DEPTH_SIZE, &glVisual->depthSize);
  573.   GL_GET_CONFIG(GLX_STENCIL_SIZE, &glVisual->stencilSize);
  574.   GL_GET_CONFIG(GLX_ACCUM_RED_SIZE, &glVisual->accumRedSize);
  575.   GL_GET_CONFIG(GLX_ACCUM_GREEN_SIZE, &glVisual->accumGreenSize);
  576.   GL_GET_CONFIG(GLX_ACCUM_BLUE_SIZE, &glVisual->accumBlueSize);
  577.   GL_GET_CONFIG(GLX_ACCUM_ALPHA_SIZE, &glVisual->accumAlphaSize);
  578.  
  579.   return(1);
  580. }
  581.  
  582. int
  583. PrintCookedVisualInfo (
  584.     Display    *dpy,
  585.     XVisualInfo *visual,
  586.     int indent
  587. )
  588. {
  589.   int result;
  590.   int hasRGB, hasAlpha, hasDepth, hasStencil, hasAccum, hasAuxBuffers;
  591.   GLXVisualInfo glVisualInfo;
  592.   GLXVisualInfo *gl = &glVisualInfo;
  593.   int listEmpty;
  594.  
  595.   printf ("%s visual: ID = 0x%lx (hex) %d (decimal) screen = %d\n",
  596.       VisualClassName(visual->class) , visual->visualid, visual->visualid,
  597.       visual->screen);
  598.  
  599.   if (result = GetGLVisualInfo(dpy, visual, gl)) {
  600.  
  601.     hasRGB = ((gl->redSize != 0)   ||
  602.           (gl->greenSize != 0) ||
  603.           (gl->blueSize != 0));
  604.     hasAlpha = (gl->alphaSize != 0);
  605.     hasDepth = (gl->depthSize != 0);
  606.     hasStencil = (gl->stencilSize != 0);
  607.     hasAccum = ((gl->accumRedSize != 0)   ||
  608.         (gl->accumGreenSize != 0) ||
  609.         (gl->accumBlueSize != 0)  ||
  610.         (gl->accumAlphaSize != 0));
  611.     hasAuxBuffers = (gl->auxBuffers != 0);
  612.  
  613.  
  614.     printf("%*s", indent, "");
  615.     if (gl->level < 0) {
  616.       printf("UNDERLAY(%d) ", -gl->level);
  617.     }
  618.     if (gl->level > 0) {
  619.       printf("OVERLAY(%d) ", gl->level);
  620.     }
  621.     if (gl->doubleBuffer)
  622.       printf("DOUBLE buffered ");
  623.     else
  624.       printf("SINGLE buffered ");
  625.  
  626.     if (gl->stereo)
  627.       printf("STEREO ");
  628.     else
  629.       printf("MONO ");
  630.  
  631.     /*
  632.      * RGBA visual
  633.      */
  634.     if (gl->rgba) {               /* rgba visual */
  635.       printf("RGB visual ");
  636.  
  637.       listEmpty = GL_TRUE;
  638.       if (hasAlpha || hasDepth || hasStencil || hasAccum || hasAuxBuffers) {
  639.     printf("with (");
  640.     if (hasAlpha) {
  641.       if (listEmpty) listEmpty = GL_FALSE; else printf(" ");
  642.       printf("Alpha");
  643.     }
  644.     if (hasDepth) {
  645.       if (listEmpty) listEmpty = GL_FALSE; else printf(" ");
  646.       printf("Z");
  647.     }
  648.     if (hasStencil) {
  649.       if (listEmpty) listEmpty = GL_FALSE; else printf(" ");
  650.       printf("Stencil");
  651.     }
  652.     if (hasAccum) {
  653.       if (listEmpty) listEmpty = GL_FALSE; else printf(" ");
  654.       printf("Accum");
  655.     }
  656.     if (hasAuxBuffers) {
  657.       if (listEmpty) listEmpty = GL_FALSE; else printf(" ");
  658.       printf("%d Aux Buffers");
  659.     }
  660.     printf(")\n");
  661.       }
  662.  
  663.       printf("%*s", indent, "");
  664.       printf("GL Sizes: RGBA=(%d,%d,%d,%d), ",
  665.          gl->redSize, gl->greenSize, gl->blueSize, gl->alphaSize);
  666.       if (hasDepth)
  667.     printf("Z=%d, ", gl->depthSize);
  668.       if (hasStencil)
  669.     printf("Stencil=%d, ", gl->stencilSize);
  670.       if (hasAccum)
  671.     printf("Accum=(%d,%d,%d,%d)",
  672.            gl->accumRedSize, gl->accumGreenSize, gl->accumBlueSize,
  673.            gl->accumAlphaSize);
  674.       printf("\n");
  675.  
  676.       /*
  677.        * Do some simple sanity checks on rgba visual.
  678.        */
  679.       if (!hasRGB)
  680.     printf("%*sERROR: RGBA visual, but RGB have zero size\n",
  681.            indent, "");
  682.       if (hasAlpha && hasAccum && gl->accumAlphaSize == 0)
  683.     printf("%*sERROR: RGBA visual with Alpha and Accum, but Accum Alpha size is zero\n",
  684.            indent, "");
  685.     }                       /* end rgba visual */
  686.     /*
  687.      * COLOR INDEX visual
  688.      */
  689.     else {                   /* color index visual */
  690.       printf("COLOR INDEX visual ");
  691.  
  692.       listEmpty = GL_TRUE;
  693.       if (hasDepth || hasStencil || hasAuxBuffers) {
  694.     printf("with (");
  695.     if (hasDepth) {
  696.       if (listEmpty) listEmpty = GL_FALSE; else printf(" ");
  697.       printf("Z");
  698.     }
  699.     if (hasStencil) {
  700.       if (listEmpty) listEmpty = GL_FALSE; else printf(" ");
  701.       printf("Stencil");
  702.     }
  703.     if (hasAuxBuffers) {
  704.       if (listEmpty) listEmpty = GL_FALSE; else printf(" ");
  705.       printf("%d Aux Buffers");
  706.     }
  707.     printf(")\n");
  708.       }
  709.  
  710.       printf("%*s", indent, "");
  711.       printf("GL Sizes: ColorIndex=%d, ", gl->bufferSize);
  712.       if (hasDepth)
  713.     printf("Z=%d, ", gl->depthSize);
  714.       if (hasStencil)
  715.     printf("Stencil=%d", gl->stencilSize);
  716.       printf("\n");
  717.  
  718.       /*
  719.        * Do some simple sanity checks on color index visual.
  720.        */
  721.       if (hasRGB)
  722.     printf("%*sERROR: CI visual, but RGB has non-zero sizes (%d,%d,%d)\n",
  723.            indent, "", gl->redSize, gl->greenSize, gl->blueSize);
  724.       if (hasAlpha)
  725.     printf("%*sERROR: CI visual, but Alpha has non-zero size = %d\n",
  726.            indent, "", gl->alphaSize);
  727.       if (hasAccum)
  728.     printf("%*sERROR: CI visual, but Accum has non-zero sizes (%d,%d,%d,%d)\n",
  729.            indent, "", gl->accumRedSize, gl->accumGreenSize,
  730.            gl->accumBlueSize, gl->accumAlphaSize);
  731.     }                       /* end color index visual */
  732.   }
  733.   else {
  734.     printf("%*s", indent, "");
  735.     printf("GL NOT SUPPORTED\n");
  736.   }
  737.  
  738.   printf("%*sCore X: ", indent, "");
  739.   printf ("depth=%d, ", visual->depth);
  740.   printf ("colormapSize=%d ", visual->colormap_size);
  741.  
  742.   if ((visual->class == TrueColor) || (visual->class == DirectColor)) {
  743.     printf ("RGB: masks=(0x%lx,0x%lx,0x%lx) ",
  744.         visual->red_mask, visual->green_mask, visual->blue_mask);
  745.     printf ("bits=%d",
  746.         visual->bits_per_rgb);
  747.   }
  748.   printf("\n");
  749. }
  750.  
  751. int
  752. PrintRawVisualInfo (
  753.     Display    *dpy,
  754.     XVisualInfo *visual,
  755.     int indent
  756. )
  757. {
  758.   int result;
  759.   GLXVisualInfo glVisualInfo;
  760.   GLXVisualInfo *gl = &glVisualInfo;
  761.  
  762.   printf ("%s visual: ID = 0x%lx (hex) %d (decimal) screen = %d\n",
  763.       VisualClassName(visual->class) , visual->visualid, visual->visualid,
  764.       visual->screen);
  765.   
  766.   if (result = GetGLVisualInfo(dpy, visual, gl)) {
  767.  
  768.     printf("%*s", indent, "");
  769.     printf("useGL=%d, level=%d, doubleBuffer=%d, rgba=%d, stereo=%d\n",
  770.        gl->useGL, gl->level, gl->doubleBuffer, gl->rgba, gl->stereo);
  771.  
  772.     printf("%*s", indent, "");
  773.     printf("bufferSize=%d, number aux buffers=%d\n",
  774.        gl->bufferSize, gl->auxBuffers);
  775.  
  776.     printf("%*s", indent, "");
  777.     printf("sizes: RGBA=(%d,%d,%d,%d), Z=%d, STENCIL=%d, ACCUM=(%d,%d,%d,%d)\n",
  778.        gl->redSize, gl->greenSize, gl->blueSize, gl->alphaSize,
  779.        gl->depthSize, gl->stencilSize, 
  780.        gl->accumRedSize, gl->accumGreenSize,
  781.        gl->accumBlueSize, gl->accumAlphaSize);
  782.  
  783.   }
  784.   else {
  785.     printf("%*s", indent, "");
  786.     printf("GL NOT SUPPORTED\n");
  787.   }
  788.  
  789.   printf("%*sCore X: ", indent, "");
  790.   printf ("depth=%d, ", visual->depth);
  791.   printf ("colormapSize=%d ", visual->colormap_size);
  792.   printf ("RGB: masks=(0x%lx,0x%lx,0x%lx) ",
  793.       visual->red_mask, visual->green_mask, visual->blue_mask);
  794.   printf ("bits=%d",
  795.       visual->bits_per_rgb);
  796.   printf("\n");
  797. }
  798.  
  799. void
  800. PrintScreenInfo(
  801.   Display    *dpy,
  802.   int         scr,
  803.   int         fieldNameLen,
  804.   int          indent
  805. )
  806. {
  807.   Screen     *s = ScreenOfDisplay(dpy, scr);    /* opaque structure */
  808.   int         i;        /* temp variable: iterator */
  809.   static char *yes = "YES", *no = "NO", *when = "WHEN MAPPED";
  810.   double      xres, yres;
  811.   int         ndepths = 0, *depths = NULL;
  812.   char        title[256];
  813.   int         titleLen, fillLen;
  814.  
  815.   sprintf(title, " Screen %d ", scr);
  816.   titleLen = strlen(title);
  817.   fillLen = (pageWidth - titleLen) / 2;
  818.   for (i = 0; i < fillLen; i++) printf("%c", '=');
  819.   printf("%s", title);
  820.   for (i = 0; i < fillLen; i++) printf("%c", '=');
  821.   printf("\n");  
  822.  
  823.   /*
  824.    * there are 2.54 centimeters to an inch; so there are 25.4 millimeters.
  825.    * 
  826.    * dpi = N pixels / (M millimeters / (25.4 millimeters / 1 inch)) = N pixels /
  827.    * (M inch / 25.4) = N * 25.4 pixels / M inch
  828.    */
  829.  
  830.   xres = ((((double) DisplayWidth(dpy, scr)) * 25.4) /
  831.       ((double) DisplayWidthMM(dpy, scr)));
  832.   yres = ((((double) DisplayHeight(dpy, scr)) * 25.4) /
  833.       ((double) DisplayHeightMM(dpy, scr)));
  834.  
  835.   printf("%*s%d\n",
  836.      fieldNameLen, "screen:",
  837.      scr);
  838.   printf("%*s%dx%d pixels (%dx%d millimeters)\n",
  839.          fieldNameLen, "dimensions:",
  840.      DisplayWidth(dpy, scr), DisplayHeight(dpy, scr),
  841.      DisplayWidthMM(dpy, scr), DisplayHeightMM(dpy, scr));
  842.  
  843.   printf("%*s%dx%d dots per inch\n",
  844.      fieldNameLen, "resolution:",
  845.      (int) (xres + 0.5), (int) (yres + 0.5));
  846.   depths = XListDepths(dpy, scr, &ndepths);
  847.   if (!depths)
  848.     ndepths = 0;
  849.   printf("%*s(%d total):       ",
  850.      fieldNameLen, "depths:", ndepths);
  851.   for (i = 0; i < ndepths; i++) {
  852.     printf("%d", depths[i]);
  853.     if (i < ndepths - 1) {
  854.       putchar(',');
  855.       putchar(' ');
  856.     }
  857.   }
  858.   putchar('\n');
  859.   if (depths)
  860.     XFree((char *) depths);
  861.   printf("%*s0x%lx\n",
  862.      fieldNameLen, "root window id:", RootWindow(dpy, scr));
  863.   printf("%*s%d plane%s\n",
  864.      fieldNameLen, "depth of root window:",
  865.      DisplayPlanes(dpy, scr),
  866.      DisplayPlanes(dpy, scr) == 1 ? "" : "s");
  867.   printf("%*sminimum %d, maximum %d\n",
  868.      fieldNameLen, "number colormaps:",
  869.      MinCmapsOfScreen(s), MaxCmapsOfScreen(s));
  870.   printf("%*s0x%lx, number colormap cells %d\n",
  871.      fieldNameLen, "default colormap:",
  872.      DefaultColormap(dpy, scr), DisplayCells(dpy, scr));
  873.   printf("%*sblack 0x%lx, white 0x%lx\n",
  874.      fieldNameLen, "preallocated pixels:",  
  875.      BlackPixel(dpy, scr), WhitePixel(dpy, scr));
  876.   printf("%*sbacking-store %s, save-unders %s\n",
  877.      fieldNameLen, "options:",
  878.      (DoesBackingStore(s) == NotUseful) ? no :
  879.      ((DoesBackingStore(s) == Always) ? yes : when),
  880.      DoesSaveUnders(s) ? yes : no);
  881.   printf("%*s0x%lx\n",
  882.      fieldNameLen, "input event mask:", EventMaskOfScreen(s));
  883.   PrintEventMask(fieldNameLen > 0 ? fieldNameLen : -fieldNameLen,
  884.          EventMaskOfScreen(s));
  885.  
  886.  
  887.   return;
  888. }
  889.  
  890. void
  891. PrintScreenVisualInfo(
  892.   Display    *dpy,
  893.   int         scr,
  894.   int         fieldNameLen,
  895.   int          indent
  896. )
  897. {
  898.   XVisualInfo visualTemplate;        /* fill in for getting info */
  899.   XVisualInfo *visuals;        /* retured info */
  900.   int         nVisuals;        /* number of elements returned */
  901.   int         i;
  902.   char        title[256];
  903.   int         titleLen, fillLen;
  904.  
  905.   nVisuals = 0;
  906.   visualTemplate.screen = scr;
  907.   visuals = XGetVisualInfo(dpy, VisualScreenMask, &visualTemplate, &nVisuals);
  908.  
  909.   sprintf(title, " %d Visuals for Screen %d (default = 0x%lx) ",
  910.       nVisuals, scr, XVisualIDFromVisual(DefaultVisual(dpy, scr)));
  911.   titleLen = strlen(title);
  912.   fillLen = (pageWidth - titleLen) / 2;
  913.   for (i = 0; i < fillLen; i++) printf("%c", '=');
  914.   printf("%s", title);
  915.   for (i = 0; i < fillLen; i++) printf("%c", '=');
  916.   printf("\n");  
  917.  
  918.   for (i = 0; i < nVisuals; i++) {
  919.     if (printCookedVisualInfo)
  920.       PrintCookedVisualInfo (dpy, &visuals[i], indent);
  921.     if (printRawVisualInfo)
  922.       PrintRawVisualInfo (dpy, &visuals[i], indent);
  923.     printf("\n");
  924.   }
  925.   if (visuals)
  926.     XFree((char *) visuals);
  927.  
  928. }
  929.  
  930. /*****************************************************************************/
  931. /****************************  Exported Functions  ***************************/
  932. /*****************************************************************************/
  933.  
  934. int
  935. main(
  936.       int argc,
  937.       char *argv[]
  938. )
  939. {
  940.   Display    *dpy;        /* X connection */
  941.   int         screenNum;
  942.   int         fieldNameLen = -24;
  943.   int         indent = 2;
  944.  
  945.   ProcessArgs(argc, argv);
  946.  
  947.   dpy = XOpenDisplay(displayname);
  948.   if (!dpy) {
  949.     fprintf(stderr, "%s:  unable to open display \"%s\".\n",
  950.         ProgramName, XDisplayName(displayname));
  951.     exit(1);
  952.   }
  953.  
  954.   dpyHasGL = glXQueryExtension(dpy, &glErrorBase, &glEventBase);
  955.  
  956.   if (printDisplayInfo) PrintDisplayInfo(dpy, fieldNameLen);
  957.  
  958.   for (screenNum = 0; screenNum < ScreenCount(dpy); screenNum++) {
  959.     if (printScreenInfo)
  960.       PrintScreenInfo(dpy, screenNum, fieldNameLen, indent);
  961.     if (printRawVisualInfo || printCookedVisualInfo)
  962.       PrintScreenVisualInfo(dpy, screenNum, fieldNameLen, indent);
  963.   }
  964.  
  965.   return(XCloseDisplay(dpy));
  966. }
  967.